package com.spring.demo.app.web.response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;


/**
 * <p></p>
 * @author yangheng@cmhk.com
 * @since 1.0.0-snapshot   
 * @date 2016-6-13 下午6:53:38
 */
public class IPage<E> {
  private static final long serialVersionUID = 1L;

  static Logger logger = LoggerFactory.getLogger(IPage.class);

  /**
   * 不进行count查询
   */
  private static final int NO_SQL_COUNT = -1;
  /**
   * 进行count查询
   */
  private static final int SQL_COUNT = 0;
  /**
   * 页码，从1开始
   */
  private int pageNum;
  /**
   * 页面大小
   */
  private int pageSize;
  /**
   * 起始行
   */
  private int startRow;
  /**
   * 末行
   */
  private int endRow;
  /**
   * 总数
   */
  private long total;
  /**
   * 总页数
   */
  private int pages;
  /**
   * 分页合理化
   */
  private Boolean reasonable;
  /**
   * 当设置为true的时候，如果pagesize设置为0（或RowBounds的limit=0），就不执行分页，返回全部结果
   */
  private Boolean pageSizeZero;

  private List<E> result;

  public IPage() {
      logger.info("IPage Create");
  }

  public IPage(int pageNum, int pageSize) {
      this(pageNum, pageSize, SQL_COUNT, null);
  }

  public IPage(int pageNum, int pageSize, boolean count) {
      this(pageNum, pageSize, count ? IPage.SQL_COUNT : IPage.NO_SQL_COUNT, null);
  }

  private IPage(int pageNum, int pageSize, int total, Boolean reasonable) {
      if (pageNum == 1 && pageSize == Integer.MAX_VALUE) {
          pageSizeZero = true;
          this.pageSize = 0;
      }
      this.pageNum = pageNum;
      this.pageSize = pageSize;
      this.total = total;
      calculateStartAndEndRow();
      setReasonable(reasonable);
  }

  /**
   * int[] rowBounds
   *    0 : offset
   *    1 : limit
   */
  public IPage(int[] rowBounds, boolean count) {
      this(rowBounds, count ? IPage.SQL_COUNT : IPage.NO_SQL_COUNT);
  }

  /**
   * int[] rowBounds
   *    0 : offset
   *    1 : limit
   */
  public IPage(int[] rowBounds, int total) {
      if (rowBounds[0] == 0 && rowBounds[1] == Integer.MAX_VALUE) {
          pageSizeZero = true;
          this.pageSize = 0;
      } else {
          this.pageSize = rowBounds[1];
      }
      this.startRow = rowBounds[0];
      //RowBounds方式默认不求count总数，如果想求count,可以修改这里为SQL_COUNT
      this.total = total;
      this.endRow = this.startRow + rowBounds[1];
  }

  public void setResult(List<E> result){
     this.result = result;
  }
  
  public List<E> getResult() {
      return this.result;
  }

  public int getPages() {
      return pages;
  }

  public int getEndRow() {
      return endRow;
  }

  public int getPageNum() {
      return pageNum;
  }

  public void setPageNum(int pageNum) {
      //分页合理化，针对不合理的页码自动处理
      this.pageNum = ((reasonable != null && reasonable) && pageNum <= 0) ? 1 : pageNum;
  }

    public void setStartRow(int startRow) {
        this.startRow = startRow;
    }

    public void setEndRow(int endRow) {
        this.endRow = endRow;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

  public int getPageSize() {
      return pageSize;
  }

  public void setPageSize(int pageSize) {
      this.pageSize = pageSize;
  }

  public int getStartRow() {
      return startRow;
  }

  public long getTotal() {
      return total;
  }

  public void setTotal(long total) {
      this.total = total;
      if (pageSize > 0) {
          pages = (int) (total / pageSize + ((total % pageSize == 0) ? 0 : 1));
      } else {
          pages = 0;
      }
      //分页合理化，针对不合理的页码自动处理
      if ((reasonable != null && reasonable) && pageNum > pages) {
          pageNum = pages;
          calculateStartAndEndRow();
      }
  }

  public void setReasonable(Boolean reasonable) {
      if (reasonable == null) {
          return;
      }
      this.reasonable = reasonable;
      //分页合理化，针对不合理的页码自动处理
      if (this.reasonable && this.pageNum <= 0) {
          this.pageNum = 1;
          calculateStartAndEndRow();
      }
  }

  public Boolean getReasonable() {
      return reasonable;
  }

  public Boolean getPageSizeZero() {
      return pageSizeZero;
  }

  public void setPageSizeZero(Boolean pageSizeZero) {
      if (pageSizeZero != null) {
          this.pageSizeZero = pageSizeZero;
      }
  }

  /**
   * 计算起止行号
   */
  private void calculateStartAndEndRow() {
      this.startRow = this.pageNum > 0 ? (this.pageNum - 1) * this.pageSize : 0;
      this.endRow = this.startRow + this.pageSize * (this.pageNum > 0 ? 1 : 0);
  }

  public boolean isCount() {
      return this.total > NO_SQL_COUNT;
  }

  //增加链式调用方法

  /**
   * 设置页码
   *
   * @param pageNum
   * @return
   */
  public IPage<E> pageNum(int pageNum) {
      //分页合理化，针对不合理的页码自动处理
      this.pageNum = ((reasonable != null && reasonable) && pageNum <= 0) ? 1 : pageNum;
      return this;
  }

  /**
   * 设置页面大小
   *
   * @param pageSize
   * @return
   */
  public IPage<E> pageSize(int pageSize) {
      this.pageSize = pageSize;
      calculateStartAndEndRow();
      return this;
  }

  /**
   * 是否执行count查询
   *
   * @param count
   * @return
   */
  public IPage<E> count(Boolean count) {
      this.total = count ? IPage.SQL_COUNT : IPage.NO_SQL_COUNT;
      return this;
  }

  /**
   * 设置合理化
   *
   * @param reasonable
   * @return
   */
  public IPage<E> reasonable(Boolean reasonable) {
      setReasonable(reasonable);
      return this;
  }

  /**
   * 当设置为true的时候，如果pagesize设置为0（或RowBounds的limit=0），就不执行分页，返回全部结果
   *
   * @param pageSizeZero
   * @return
   */
  public IPage<E> pageSizeZero(Boolean pageSizeZero) {
      setPageSizeZero(pageSizeZero);
      return this;
  }

  @Override
  public String toString() {
      final StringBuilder sb = new StringBuilder("IPage{");
      sb.append("pageNum=").append(pageNum);
      sb.append(", pageSize=").append(pageSize);
      sb.append(", startRow=").append(startRow);
      sb.append(", endRow=").append(endRow);
      sb.append(", total=").append(total);
      sb.append(", pages=").append(pages);
      sb.append(", reasonable=").append(reasonable);
      sb.append(", pageSizeZero=").append(pageSizeZero);
      sb.append('}');
      return sb.toString();
  }
}
